/*
 * BatLogger.c
 *
 * Created: 05.09.2014 14:00:49
 *  Author: Pasha
 */ 


#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <util/delay.h>

#define CHAN_REFERENCE		0x1E
#define CHAN_ADC			6
#define LED					(1<<PORTA4)
#define BUTTON_START		(1<<PORTA0)
#define BUTTON_STOP			(1<<PORTA1)

#define	LED_ON()			do { PORTA |=  LED; } while (0)
#define	LED_OFF()			do { PORTA &= ~LED; } while (0)
#define LED_TOGGLE()		do { PINA   =  LED; } while (0)

volatile unsigned int Value, Reference;
volatile unsigned int VCC, Battery;
unsigned int cnt=0;

unsigned char EEMEM eBatVoltage[512];

#define _delay_s(sec)				\
{									\
	uint16_t cnt;					\
	for (cnt=1000; cnt>0; cnt--)	\
		_delay_ms(sec);				\
}

#define _delay_min(min)				\
{									\
	uint8_t cnt;					\
	for (cnt=60; cnt>0; cnt--)		\
	_delay_s(min);					\
}


inline void Init (void)
{
	// Init GPIOs
	DDRA = LED;
	PORTA = BUTTON_START | BUTTON_STOP;
	
	// Init ADC
	ADCSRB = 0;
	DIDR0  = (1<<ADC6D);
	ADCSRA = (1<<ADEN)|(1<<ADSC)|(6<<ADPS0);
	while (bit_is_set(ADCSRA, ADSC));
	ADCSRA |= (1<<ADIF);
	
}

unsigned int ReadADC (unsigned char channel)
{
	unsigned char cnt;
	unsigned int data, retval=0;
	
	ADMUX &= 0xE0;
	ADMUX |= (0x1F&channel);
	if (channel == CHAN_REFERENCE)
		_delay_ms(1.5);
	for (cnt=0; cnt<8; cnt++)
	{
		ADCSRA |= (1<<ADSC);
		while (bit_is_set(ADCSRA, ADSC));
		ADCSRA |= (1<<ADIF);
		data  = (unsigned int)(ADCL);
		data |= (unsigned int)(ADCH<<8);
		retval += data;
	}
	retval /= 8;
	return retval;
}

int main(void)
{
	
	
	Init();
	
	while (PINA & BUTTON_START)
	{
		LED_ON();
		_delay_ms(250);
		LED_OFF();
		_delay_ms(250);
	}
	
	while(cnt < 512)
    {
		LED_ON();
		Reference = ReadADC(CHAN_REFERENCE);
		VCC = (55UL * 1023) / Reference;
		Value = ReadADC(CHAN_ADC);
		Battery = ((unsigned long)(VCC) * Value) / 1023;
		eeprom_busy_wait();
		eeprom_write_byte(&eBatVoltage[cnt], Battery);
		++cnt;
		_delay_s(1);
		LED_OFF();
		/*
		_delay_s(59);
		_delay_min(4);
		*/
		_delay_s(11);
    }
	LED_ON();
	while (1);
}
